package com.foxchen.decrypt.autoconfigure;

import com.foxchen.decrypt.bean.DataSourceExtendProperties;
import com.foxchen.decrypt.service.DbInitCheckService;
import com.foxchen.decrypt.service.DbInitService;
import com.foxchen.decrypt.utils.AesUtil;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import javax.sql.XADataSource;
import java.util.Properties;

@Slf4j
@Configuration
@EnableConfigurationProperties(value = DataSourceExtendProperties.class)
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
@ConditionalOnClass({HikariDataSource.class})
@ConditionalOnProperty(name = {"spring.datasource.type"}, havingValue = "com.zaxxer.hikari.HikariDataSource")
public class DecryptDataSourceAutoConfigure {

    /**
     * 如果有自定义的hikari配置 直接使用自定义的
     */
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public HikariConfig hikariConfig(DataSourceExtendProperties properties) throws Exception {
        HikariConfig config = new HikariConfig();
        config.setDriverClassName(properties.getDriverClassName());
        config.setJdbcUrl(properties.getUrl());
        config.setUsername(properties.getUsername());
        if (properties.getName() != null) {
            config.setPoolName(properties.getName());
        }
        String password = properties.getPassword();
        if(Boolean.TRUE.equals(properties.getEncrypt())){
            password = AesUtil.decryptAes(password);
        }
        config.setPassword(password);

        Properties p = new Properties();
        p.put("socketTimeout", "1200");
        p.put("connectTimeout", "20");
        p.put("tcpKeepAlive", "true");
        config.setDataSourceProperties(p);

        log.info("hikariConfig={}",config);
        DbInitService.init(config);
        return config;
    }

    /**
     * 根据hikari配置 创建hikari数据库连接池
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean({DataSource.class, XADataSource.class})
    public DataSource dataSource(HikariConfig hikariConfig) {
        log.info("begin create hikari datasource,config={}",hikariConfig);
        return new HikariDataSource(hikariConfig);
    }

    /**
     * 检查数据库
     */
    @Bean
    public DbInitCheckService dbInitCheckService(DataSource ds) {
        log.info("begin dbInitCheckService");
        return new DbInitCheckService(ds);
    }
}
